package com.example.common.net


import com.zyj.retrofit.adapter.FlowCallAdapterFactory
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

class RetrofitFactory private constructor() {
    /**
     * 懒加载Retrofit实例
     * 通过lazy委托确保Retrofit只初始化一次
     */
    private val retrofit: Retrofit by lazy { initRetrofit() }

    /**
     * 初始化Retrofit实例
     * 配置基础URL、JSON转换器、协程适配器和HTTP客户端
     * @return 配置完成的Retrofit实例
     */
    private fun initRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl(BuildConfig.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(FlowCallAdapterFactory.create())
            .client(createOkHttpClient())
            .build()
    }

    /**
     * 创建配置好的OkHttpClient实例
     * 设置连接、读取、写入超时时间和HTTP日志拦截器
     * @return 配置完成的OkHttpClient实例
     */
    private fun createOkHttpClient() = OkHttpClient.Builder()
        .connectTimeout(TIMEOUT, TimeUnit.SECONDS)
        .readTimeout(TIMEOUT, TimeUnit.SECONDS)
        .writeTimeout(TIMEOUT, TimeUnit.SECONDS)
        .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
        .build()

    companion object {
        /**
         * 网络请求超时时间常量，单位秒
         */
        private const val TIMEOUT = 30L

        /**
         * Retrofit工厂单例实例
         * 使用线程安全的懒加载模式确保多线程环境下的安全性
         */
        val instance: RetrofitFactory by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            RetrofitFactory()
        }
    }

    /**
     * 创建指定类型的网络服务接口实例
     * 使用内联和重ified关键字支持运行时获取泛型类型
     * @param T 网络服务接口类型
     * @return 指定类型的网络服务接口实例
     */
    inline fun <reified T> create(): T = create(T::class.java)

    /**
     * 创建指定类型的网络服务接口实例
     * @param service 网络服务接口的Class对象
     * @param T 网络服务接口类型
     * @return 指定类型的网络服务接口实例
     */
    fun <T> create(service: Class<T>): T {
        return retrofit.create(service)
    }

}

